﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace FileExplorer
{
    public partial class ExplorerForm : Form
    {
        //SystemDirTree tree;

        public ExplorerForm()
        {
            InitializeComponent();
            //loadIcons();

            //IconData.Test(this);
            //String data = new ImageData().ToJson();
            //MessageBox.Show(data);

            // 在listView中显示目录信息
            //DriverInfo driver = new DriverInfo();
            //string data = driver.ToJson();
            new DriverInfo().ShowIn(listView1);

            // 在treeView中显示系统目录
            //tree = new SystemDirTree();
            //string Str = tree.ToJson();
            new SystemDirTree().ShowIn(treeView1);
        }

        /// <summary>
        /// 在listView中显示指定的目录
        /// </summary>
        private void refresh_Click(object sender, EventArgs e)
        {
            String FullName = FilePath.Text.Trim();
            //ShowFolder(listView1, FullName);

            DirInfo info = new DirInfo(FullName);
            String data = info.ToJson();

            info.ShowIn(listView1);
        }

        /// <summary>
        /// 选中指定的文件夹，在listView中显示文件信息，地址栏中显示路径
        /// </summary>
        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            TreeNode node = e.Node;
            String tag = node.Tag as String;
            String str = tag;

            String path = tag.Substring(tag.IndexOf(":") + 1);
            FilePath.Text = path;

            if (tag.StartsWith("Driver:"))      // 显示磁盘信息
            {
                new DriverInfo().ShowIn(listView1);
            }
            else if (tag.StartsWith("Dir:"))    // 显示目录信息
            {
                String dir = tag.Substring(tag.IndexOf(":") + 1);
                new DirInfo(dir).ShowIn(listView1);
            }
        }

        /// <summary>
        /// 打开指定的文件夹，在listView中显示文件信息，地址栏中显示路径
        /// </summary>
        private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (listView1.SelectedItems.Count > 0)
            {
                ListViewItem select = listView1.SelectedItems[0];
                String tag = select.Tag as String;

                String path = tag.Substring(tag.IndexOf(":") + 1);
                FilePath.Text = path;

                if (tag.StartsWith("Dir:")) new DirInfo(path).ShowIn(listView1);
                else if (tag.StartsWith("File:")) System.Diagnostics.Process.Start(path);
            }
        }

        bool isCopyFile = false; // 是否为复制文件
        List<String> SelectedFiles = new List<string>();
        private void getSelectedFile(ListView listView)
        {
            SelectedFiles = new List<string>();
            if (listView1.SelectedItems.Count > 0)
            {
                foreach (ListViewItem item in listView.SelectedItems)
                {
                    SelectedFiles.Add(item.Tag as String);
                }
            }
        }

        private void 复制ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getSelectedFile(listView1);
            isCopyFile = true; 
        }

        private void 剪切ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            getSelectedFile(listView1);
            isCopyFile = false;
        }

        private void 粘贴ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            String dir = FilePath.Text;
            if (!Directory.Exists(dir)) return;

            if (!dir.EndsWith("\\")) dir += "\\";
            foreach (String tag in SelectedFiles)
            {
                String path = tag.Substring(tag.IndexOf(":") + 1);

                if(tag.StartsWith("File:"))
                { 
                    String name = Path.GetFileName(path);
                    String newPath = dir + name;

                    if (path.Equals(newPath)) continue;
                    if (isCopyFile) File.Copy(path, newPath, true);
                    else File.Move(path, newPath);

                }
                else if (tag.StartsWith("Dir:"))                // 文件夹重命名
                {
                    DirectoryInfo info = new DirectoryInfo(path);
                    String newPath = dir + info.Name;

                    if (path.Equals(newPath)) continue;
                    if (isCopyFile) CopyFolderTo(path, newPath, true);
                    else Directory.Move(path, newPath);
                }
            }
            SelectedFiles.Clear();                  // 清空复制或剪切的文件信息

            new DirInfo(dir).ShowIn(listView1);     // 刷新显示文件列表信息

        }

        /// <summary>
        /// 从一个目录将其内容复制到另一目录
        /// </summary>
        public static void CopyFolderTo(string dirSource, string dirTarget, bool overwirite)
        {
            // 先获取Source目录下，当前的文件目录信息。在复制前先读取文件和目录信息，避免父目录向子目录复制时出现的无限复制循环，而只执行一次复制
            DirectoryInfo directoryInfo = new DirectoryInfo(dirSource);
            FileInfo[] files = directoryInfo.GetFiles();
            DirectoryInfo[] directoryInfoArray = directoryInfo.GetDirectories();

            //检查目标路径是否存在目的目录
            if (!Directory.Exists(dirTarget)) Directory.CreateDirectory(dirTarget);

            //先来复制所有文件  
            foreach (FileInfo file in files)
            {
                string fileSource = Path.Combine(file.DirectoryName, file.Name);
                string fileTarget = Path.Combine(dirTarget, file.Name);
                file.CopyTo(fileTarget, overwirite);
            }

            //最后复制目录
            foreach (DirectoryInfo dir in directoryInfoArray)
            {
                CopyFolderTo(Path.Combine(dirSource, dir.Name), Path.Combine(dirTarget, dir.Name), overwirite);
            }
        }

        private void 重命名ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count > 0)
            {
                ListViewItem ReNameItem = listView1.SelectedItems[0];   // 获取重命名的列表项
                String tag = ReNameItem.Tag as String;                  // 获取数据信息
                if (tag.StartsWith("File:") || tag.StartsWith("Dir:"))
                {
                    String path = tag.Substring(tag.IndexOf(":") + 1);  // 文件或目录路径

                    String dir = Path.GetDirectoryName(path);           // 获取父目录
                    if (dir != null)
                    {
                        listView1.LabelEdit = true;
                        listView1.SelectedItems[0].BeginEdit();
                    }
                }
            }
        }

        private void listView1_AfterLabelEdit(object sender, LabelEditEventArgs e)
        {
            String newName = e.Label;                           // 新名称
            int index = e.Item;
            listView1.LabelEdit = false;

            ListViewItem ReNameItem = listView1.Items[index];   // 获取重命名的列表项
            String tag = ReNameItem.Tag as String;              // 获取数据信息

            String path = tag.Substring(tag.IndexOf(":") + 1);  // 文件或目录路径

            String dir = Path.GetDirectoryName(path);           // 获取父目录
            if (dir == null || newName == null)                 // 若非文件或文件夹，则不允许修改名称
            {
                e.CancelEdit = true;
                return;
            }

            if (!dir.EndsWith("\\")) dir += "\\";

            String newPath = (dir == null ? "" : dir) + newName;
            if (!path.Equals(newPath))
            {
                if (tag.StartsWith("File:"))                    // 文件重命名
                {
                    File.Move(path, newPath);
                    ReNameItem.Tag = "File:" + newPath;
                }
                else if (tag.StartsWith("Dir:"))                // 文件夹重命名
                {
                    Directory.Move(path, newPath);
                    ReNameItem.Tag = "Dir:" + newPath;
                }
            }
        }

        private void listView1_Click(object sender, EventArgs e)
        {
            listView1.LabelEdit = false;                        // 设为不可编辑
        }

        private void 删除ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (listView1.SelectedItems.Count > 0)
                {
                    DialogResult result = MessageBox.Show("确定要删除当前选中项?", "删除提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                    if (result == DialogResult.OK)
                    {
                        foreach (ListViewItem item in listView1.SelectedItems)
                        {
                            String tag = item.Tag as String;
                            String path = tag.Substring(tag.IndexOf(":") + 1);

                            if (tag.StartsWith("File:")) File.Delete(path);
                            else if (tag.StartsWith("Dir:")) Directory.Delete(path, true);

                            listView1.Items.Remove(item);
                        }
                    }
                }
            }
            catch (Exception ex) { }
        }

        //新建文本文档
        private void 文件ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                String dir = FilePath.Text;
                if (!Directory.Exists(dir)) return;
                if (!dir.EndsWith("\\")) dir += "\\";

                int i = 1;
                String path = dir + "新建文本文档.txt";
                while (File.Exists(path)) path = dir + "新建文本文档(" + (i++) + ").txt";
                File.Create(path);

                new DirInfo(dir).ShowIn(listView1);     // 刷新显示文件列表信息
                SelectIteam(listView1, "File:" + path);
            }
            catch (Exception ex)
            {
            }
        }

        //新建文件夹
        private void 目录ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                String dir = FilePath.Text;
                if (!Directory.Exists(dir)) return;
                if (!dir.EndsWith("\\")) dir += "\\";

                int i = 1;
                String path = dir + "新建文件夹";
                while (Directory.Exists(path)) path = dir + "新建文件夹(" + (i++) + ")";
                Directory.CreateDirectory(path);

                new DirInfo(dir).ShowIn(listView1);     // 刷新显示文件列表信息
                SelectIteam(listView1, "Dir:" + path);
            }
            catch (Exception ex)
            {
            }
        }

        private void SelectIteam(ListView list, String tag)
        {
            foreach (ListViewItem iteam in list.Items)
            {
                if(tag.Equals(iteam.Tag as String))
                {
                    iteam.Selected = true;

                    list.LabelEdit = true;
                    iteam.BeginEdit();

                    return;
                }
            }
        }

        List<String> preDirInfo = new List<string>();

        /// <summary>
        /// 地址栏，地址信息变动
        /// </summary>
        private void comboBox1_TextChanged(object sender, EventArgs e)
        {
            String path = FilePath.Text.Trim();
            if (!preDirInfo.Contains(path) && Directory.Exists(path))
            {
                preDirInfo.Add(path);
                FilePath.Items.Add(path);
            }
        }

        /// <summary>
        /// 返回前一目录
        /// </summary>
        private void back_Click(object sender, EventArgs e)
        {
            String path = FilePath.Text.Trim();
            if (preDirInfo.Contains(path))
            {
                int index = preDirInfo.IndexOf(path);
                if (index > 0)
                {
                    FilePath.Text = preDirInfo[index - 1];
                    refresh_Click(null, null);
                }
            }
        }

        /// <summary>
        /// 前进
        /// </summary>
        private void front_Click(object sender, EventArgs e)
        {
            String path = FilePath.Text.Trim();
            if (preDirInfo.Contains(path))
            {
                int index = preDirInfo.IndexOf(path);
                if (index < preDirInfo.Count - 1)
                {
                    FilePath.Text = preDirInfo[index + 1];
                    refresh_Click(null, null);
                }
            }
        }

        /// <summary>
        /// 文件地址变动
        /// </summary>
        private void FilePath_SelectedIndexChanged(object sender, EventArgs e)
        {
            refresh_Click(null, null);
        }

        //private void treeView1_AfterExpand(object sender, TreeViewEventArgs e)
        //{
        //    TreeNode node = e.Node;
        //    reloadSubNode(e.Node);
        //}

        ///// <summary>
        ///// 重载node节点下的子节点信息
        ///// </summary>
        //private void reloadSubNode(TreeNode node)
        //{
        //    if (node == null) return;
        //    foreach (TreeNode n in node.Nodes)
        //    {
        //        loadNodeInfo(n);
        //    }
        //}

        ///// <summary>
        ///// 载入node节点下的目录信息
        ///// </summary>
        //private void loadNodeInfo(TreeNode node)
        //{
        //    if (node == null) return;
        //    String tag = node.Tag as String;

        //    if (tag.Contains("Driver:") || tag.Contains("Dir:"))
        //    {
        //        tag = tag.Substring(tag.IndexOf(":") + 1);
        //        DirInfo dirInfo = new DirInfo(tag);

        //        dirInfo.ShowIn(node);
        //    }
        //}



        //private void initTreeView(TreeView treeView1)
        //{
        //    treeView1.Nodes.Clear();
        //    //treeView1.Nodes = new List<TreeNode>();
        //}

        //private ImageList largeImageList;

        ///// <summary>
        ///// 载入所需的Icon图像
        ///// </summary>
        //private void loadIcons()
        //{
        //    if (largeImageList == null)
        //    {
        //        largeImageList = new ImageList();
        //        largeImageList.ColorDepth = ColorDepth.Depth32Bit;
        //        //largeImageList.ImageSize = SystemInformation.IconSize;
        //        largeImageList.ImageSize = new Size(24, 24);
        //        //largeImageList.ImageSize = new Size(32, 32);
        //    }

        //    if(!largeImageList.Images.ContainsKey("文件夹")) largeImageList.Images.Add("文件夹", SystemIcon.Get(3));
        //    if (!largeImageList.Images.ContainsKey("本地磁盘")) largeImageList.Images.Add("本地磁盘", SystemIcon.Get(8));
        //    if (!largeImageList.Images.ContainsKey("计算机")) largeImageList.Images.Add("计算机", SystemIcon.Get(15));
        //    if (!largeImageList.Images.ContainsKey("桌面")) largeImageList.Images.Add("桌面", SystemIcon.Get(34));
        //}

        ///// <summary>
        ///// 添加文件对应的Icon信息到ImageList
        ///// </summary>
        //private int addFileIcon(string fullName)
        //{
        //    if (!largeImageList.Images.ContainsKey(fullName)) largeImageList.Images.Add(fullName, FileIcon.getIcon2(fullName));
        //    return largeImageList.Images.IndexOfKey(fullName);
        //}

        ///// <summary>
        ///// 在listView中显示
        ///// </summary>
        //public void ShowFolder(ListView lstView, String FullName)
        //{
        //    lstView.View = View.Details;
        //    lstView.AllowColumnReorder = true;
        //    lstView.Columns.Clear();
        //    lstView.Items.Clear();

        //    lstView.LargeImageList = largeImageList;
        //    lstView.SmallImageList = largeImageList;

        //    lstView.Columns.Add("columnsName", "名称", 270);
        //    lstView.Columns.Add("columnsType", "类型", 120);
        //    lstView.Columns.Add("columnsMax", "修改日期", 120);
        //    lstView.Columns.Add("columnsFreeSpace", "大小", 80);

        //    DirectoryInfo dirs = new DirectoryInfo(FullName);

        //    //添加文件夹
        //    foreach (DirectoryInfo dir in dirs.GetDirectories())
        //    {
        //        ListViewItem item = new ListViewItem();
        //        item.Text = dir.Name;
        //        item.Tag = dir;
        //        item.ImageIndex = largeImageList.Images.IndexOfKey("文件夹");

        //        item.SubItems.Add("文件夹");
        //        item.SubItems.Add(dir.LastWriteTime.ToString("yyyy/MM/dd HH:mm"));
        //        item.SubItems.Add("");

        //        lstView.Items.Add(item);
        //    }

        //    //添加文件
        //    foreach (FileInfo file in dirs.GetFiles())
        //    {
        //        ListViewItem item = new ListViewItem();
        //        item.Text = file.Name;
        //        item.Tag = file;
        //        item.ImageIndex = addFileIcon(file.FullName);

        //        string type = GetExtsDescription(file.Extension);
        //        string size = getSize(file.Length);

        //        item.SubItems.Add(type);
        //        item.SubItems.Add(file.LastWriteTime.ToString("yyyy/MM/dd HH:mm"));
        //        item.SubItems.Add(size);

        //        lstView.Items.Add(item);
        //    }
        //}

        ///// <summary>
        ///// 获取文件大小信息
        ///// </summary>
        //public string getSize(long FileLength)
        //{
        //    double len = Math.Round((FileLength / 1024.0), 2);
        //    if (len < 1024) return (len + " KB");
        //    else
        //    {
        //        len = Math.Round((len / 1024.0), 2);
        //        if (len < 1024) return (len + " MB");
        //        else
        //        {
        //            len = Math.Round((len / 1024.0), 2);
        //            return (len + " GB");
        //        }
        //    }
        //}

        ///// <summary>
        ///// 通过扩展名得到描述
        ///// </summary>
        ///// <param name="ext">扩展名，如.jpg</param>
        ///// <param name="description">返回描述</param>
        //public string GetExtsDescription(string ext)
        //{
        //    string description = "";

        //    //从注册表中读取扩展名相应的子键
        //    RegistryKey extsubkey = Registry.ClassesRoot.OpenSubKey(ext);
        //    if (extsubkey == null)  //没有找到，那就是这种类型
        //    {
        //        description = ext.ToUpper().Substring(1) + "文件";
        //        return description;
        //    }

        //    //取出扩展名对应的文件类型名称  
        //    string extdefaultvalue = extsubkey.GetValue(null) as string;
        //    if (extdefaultvalue == null) return description;

        //    //扩展名类型是可执行文件
        //    if (extdefaultvalue.Equals("exefile", StringComparison.InvariantCultureIgnoreCase))
        //    {
        //        //从注册表中读取文件类型名称的相应子键  
        //        RegistryKey exefilesubkey = Registry.ClassesRoot.OpenSubKey(extdefaultvalue);
        //        if (exefilesubkey != null)  //如果不为空
        //        {
        //            string exefiledescription = exefilesubkey.GetValue(null) as string;   //得到exefile描述字符串  
        //            if (exefiledescription != null)
        //            {
        //                description = exefiledescription;
        //            }
        //        }
        //        return description;
        //    }

        //    //从注册表中读取文件类型名称的相应子键  
        //    RegistryKey typesubkey = Registry.ClassesRoot.OpenSubKey(extdefaultvalue);
        //    if (typesubkey == null) return description;

        //    //得到类型描述字符串  
        //    string typedescription = typesubkey.GetValue(null) as string;
        //    if (typedescription != null) description = typedescription;

        //    return description;
        //}


    }
}
